﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeBuilder.Service;
using System.Threading;
using System.IO;

namespace CodeBuilder
{
    public partial class FrmMain : Form
    {
        // 声明全局变量
        Services s = new Services();
        // 声明要用到的线程
        Thread listenThread;

        public FrmMain()
        {
            InitializeComponent();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.onFormLoad();
        }
        // 单击连接按钮时
        private void tsbSaveCodes_Click(object sender, EventArgs e)
        {
            this.onFormLoad();
        }
        // 被调用以连接数据库，并获得一些基础信息
        private void onFormLoad()
        {
            DataTable dt = new DataTable();
            try
            {
                dt = s.GetLibrarysName();
                if (dt == null)
                {
                    MessageBox.Show("数据库连接失败，请检查连接串及服务是否开启", "错误", MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
                else
                {
                    this.cbxLibraryList.Items.Clear();
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        this.cbxLibraryList.Items.Add(dt.Rows[i][0]);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("数据库连接失败，请检查连接串及服务是否开启(" + ex.Message + ")", "错误", 
                    MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
        }
        // ComboBox 的选项改变时
        private void cbxLibraryList_SelectedIndexChanged(object sender, EventArgs e)
        {
            //ToolStripComboBox tscbx = (ToolStripComboBox)sender;
            string dbName = this.cbxLibraryList.SelectedItem.ToString();
            s.ChangeDB(dbName);
            //this.dgvMain.DataSource = s.GetInfo();
            this.loadRootNode(dbName);
        }
        // 向树中加载根节点
        private void loadRootNode(string rootNode)
        {
            this.trvTableList.Nodes.Clear();
            this.trvTableList.ShowLines = true;
            this.trvTableList.CheckBoxes = true;
            this.trvTableList.Nodes.Add(rootNode);
            this.loadChildNodes();
        }
        // 向树的根节点中加载子节点
        private void loadChildNodes()
        {
            DataTable dt = s.GetTablesName();
            foreach (DataRow dr in dt.Rows)
            {
                TreeNode tn = new TreeNode(dr[0].ToString());
                this.trvTableList.Nodes[0].Nodes.Add(tn);
            }
        }
        // 当选中/取消树中的根节点时
        private void trvTableList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Text == this.trvTableList.Nodes[0].Text)
            {
                foreach (TreeNode node in this.trvTableList.Nodes[0].Nodes)
                {
                    node.Checked = e.Node.Checked;
                }
            }
            //else
            //{
            //    foreach (TreeNode tn in this.trvTableList.Nodes[0].Nodes)
            //    {
            //        if (e.Node.Checked == false)
            //        {
            //            trvTableList.Nodes[0].Checked = false;
            //            break;
            //        }
            //    }
            //}
        }
        // 选择一个节点时（暂时无用）
        private void trvTableList_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //foreach (TabPage tp in this.tbcMain.TabPages)
            //{
            //    if (tp.Text == e.Node.Text)
            //    {
            //        tp.Select();
            //    }
            //}
        }
        // 保存所有生成的代码
        private void showMeResult()
        {
            for (int i = 0; i < this.tbcMain.TabPages.Count; i++)
            {
                if (i > 0)
                {
                    string c = this.tbcMain.TabPages[i].Text;
                    string cn = c.Substring(0, 1).ToUpper() + c.Substring(1);
                    string text = this.tbcMain.TabPages[i].Controls[0].Text;
                    this.output(cn, text);
                }
            }
        }
        // 处理 DataError 事件（小红叉）
        private void dgvMain_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            MessageBox.Show("出现了 DataGridView 无法解析的数据类型，将显示为红叉", "提示",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        
        // 准备生成代码，通过一些对话框与用户进行交互
        private void tsbBuildByChecked_Click(object sender, EventArgs e)
        {
            if (this.mnuVo.Checked == true)
            {
                if (this.tstbxCns.Text == "自定义命名空间" || this.tstbxCns.Text == string.Empty)
                {
                    if (MessageBox.Show("您没有指定命名空间，那么程序将以'vo'作为默认的命名空间。要继续吗？", "提示",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        this.resetTabControl();
                        this.createCodeOfVo();
                    }
                }
                else
                {
                    VoCodesFactroy.nameSpace = this.tstbxCns.Text; // 将自定义的命名空间保存在一个静态变量中
                    this.resetTabControl();
                    this.createCodeOfVo();
                }
            }
            if (this.mnuDAO.Checked == true)
            {
                if (this.tstbxCns.Text == "自定义命名空间" || this.tstbxCns.Text == string.Empty)
                {
                    if (MessageBox.Show("您没有指定命名空间，那么程序将以'dao'作为默认的命名空间。要继续吗？", "提示",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        this.resetTabControl();
                        this.createCodeOfVo();
                    }
                }
            }
        }
        // 销毁 TabControl 上原来的除数据页的 TabPage (如果有)
        private void resetTabControl()
        {
            // 从不是创建控件 "tbcMain" 的线程访问它。
            //listenThread = new Thread(new ThreadStart(this.runInThread));
            //listenThread.Start();
            foreach (TabPage tp in this.tbcMain.TabPages) // 将以前生成的 TabPage 销毁
            {
                if (tp != this.tbcMain.TabPages[0] && tp != null)
                {
                    tp.Dispose();
                }
            }
        }
        // 调用 runInThread() 方法生成实体类代码
        private void createCodeOfVo()
        {
            if (this.trvTableList.Nodes.Count != 0)
            {
                this.runInThread();
                VoCodesFactroy.nameSpace = "vo"; // 手动还原静态变量的值
            }
        }
        // 创建新的 TabPage、RichTextBox 对象，调用 CodesFactroy 类生成代码。并将生成的代码放入 RichTextBox
        private void runInThread()
        {
            foreach (TreeNode tn in this.trvTableList.Nodes[0].Nodes)
            {
                if (tn.Checked == true)
                {
                    TabPage tp = new TabPage(tn.Text);
                    this.tbcMain.TabPages.Add(tp);
                    RichTextBox rtbx = new RichTextBox();
                    rtbx.Dock = DockStyle.Fill;
                    tp.Margin = new Padding(3, 4, 3, 4);
                    tp.Padding = new Padding(3, 4, 3, 4);
                    tp.Controls.Add(rtbx);
                    this.dgvMain.DataSource = s.GetColumns(tn.Text);
                    DataSet ds = (DataSet)this.dgvMain.DataSource;
                    this.dgvMain.DataMember = ds.Tables[0].TableName;
                    VoCodesFactroy cf = new VoCodesFactroy(ds);
                    rtbx.Text = cf.RunInThread();
                }
            }
        }
        // 双击某一个子节点时
        private void trvTableList_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (!e.Node.Equals(this.trvTableList.Nodes[0]))
            {
                TabPage tp = new TabPage(e.Node.Text);
                this.tbcMain.TabPages.Add(tp);
                RichTextBox rtbx = new RichTextBox();
                rtbx.Dock = DockStyle.Fill;
                tp.Margin = new Padding(3, 4, 3, 4);
                tp.Padding = new Padding(3, 4, 3, 4);
                tp.Controls.Add(rtbx);
                this.dgvMain.DataSource = s.GetColumns(e.Node.Text);
                DataSet ds = (DataSet)this.dgvMain.DataSource;
                this.dgvMain.DataMember = ds.Tables[0].TableName;
                VoCodesFactroy cf = new VoCodesFactroy(ds);
                rtbx.Text = cf.RunInThread();
            }
        }
        /// <summary>
        /// 通过 StreamWriter 将数据写入文件
        /// </summary>
        public void output(string cn, string text)
        {
            StreamWriter sw = new StreamWriter(cn + ".cs", false);
            //byte[] test = new UTF8Encoding().GetBytes(part1);
            //this.writePart2();
            sw.Write(text);
            sw.Flush();
            sw.Close();
            //FileStream fs = new FileStream("test.txt", FileMode.Create, FileAccess.Write);
            //BufferedStream bf = new BufferedStream(fs);
            //bf.Write(test, 0, test.Length);
            //bf.Flush();
        }
        // 单击按钮以保存
        private void tsbSave_Click(object sender, EventArgs e)
        {
            this.showMeResult();
        }
        // 弹出设置连接字符串的窗体
        private void mnuConnectSetup_Click(object sender, EventArgs e)
        {
            FrmOperation fo = new FrmOperation();
            fo.ShowDialog(this);
        }

        // 按照选择的数据库生成一个 TabPage 用来输入 sql 语句
        TextBox tbx; // 声明全局变量，以便之后可以得到其中的值。即 sql 语句
        private void tsbtnQuery_Click(object sender, EventArgs e)
        {
            if (this.cbxLibraryList.SelectedItem != null)
            {
                TabPage tp = new TabPage(this.cbxLibraryList.SelectedItem.ToString());
                tbx = new TextBox();
                tbx.Multiline = true;
                tbx.Dock = DockStyle.Fill;
                tp.Controls.Add(tbx);
                this.tbcMain.TabPages.Add(tp);
            }
        }
        // 执行 sql 语句
        private void tsbtnGo_Click(object sender, EventArgs e)
        {
            if (this.tbx != null)
            {
                string sql = tbx.Text;
            }
        }
        
        // 同对现有状态取反来设置 mnuVo 的状态
        private void mnuVo_Click(object sender, EventArgs e)
        {
            this.mnuVo.Checked = !this.mnuVo.Checked; // CheckState 获取或设置 CheckBox 的三态状态
        }
        // 同对现有状态取反来设置 mnuDAO 的状态
        private void mnuDAO_Click(object sender, EventArgs e)
        {
            this.mnuDAO.Checked = !this.mnuDAO.Checked;
        }
    }
}